package com.fzk.router;

import com.alibaba.fastjson2.JSON;
import com.fzk.log.LogLevel;
import com.fzk.log.Logger;
import io.netty.channel.ChannelHandlerContext;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author uestcfzk
 * @datetime 2025-03-18 15-26-00
 */
public class MyDefaultCtx implements MyCtx {
    private String logId;
    private final ChannelHandlerContext channelCtx;
    private volatile ConcurrentHashMap<String, Object> logAttrs;

    public MyDefaultCtx(String logId, ChannelHandlerContext channelCtx) {
        this.logId = logId;
        this.channelCtx = channelCtx;
        setLogAttr(MyCtx.LogIdKey, logId);
    }

    @Override
    public void setLogAttr(String key, Object value) {
        if (logAttrs == null) {// double check
            synchronized (this) {
                if (logAttrs == null) logAttrs = new ConcurrentHashMap<>();
            }
        }
        logAttrs.put(key, value);
    }

    @Override
    public Object getLogAttr(String key) {
        // 引用变量暂存，避免因并发操作导致判断和取值操作之间发生引用变null
        ConcurrentHashMap<String, Object> attrs = this.logAttrs;
        if (attrs == null) return null;// 判断操作
        return attrs.get(key);// 取值操作
    }

    private String formatMsg(String msg) {
        if (logAttrs != null && !logAttrs.isEmpty()) {
            String attrsMsg = JSON.toJSONString(logAttrs);
            return String.format("attrs: %s, %s", attrsMsg, msg);
        }
        return msg;
    }

    @Override
    public String getLogId() {
        return this.logId;
    }

    @Override
    public void setLogId(String logId) {
        this.logId = logId;
        setLogAttr(MyCtx.LogIdKey, logId);
    }

    @Override
    public void fatal(String msg) {
        Logger.addMsg(LogLevel.FATAL, formatMsg(msg), 1);
    }

    @Override
    public void error(String msg) {
        Logger.addMsg(LogLevel.ERROR, formatMsg(msg), 1);
    }

    @Override
    public void warning(String msg) {
        Logger.addMsg(LogLevel.WARNING, formatMsg(msg), 1);
    }

    @Override
    public void info(String msg) {
        Logger.addMsg(LogLevel.INFO, formatMsg(msg), 1);
    }

    @Override
    public void debug(String msg) {
        Logger.addMsg(LogLevel.DEBUG, formatMsg(msg), 1);
    }

    @Override
    public void fine(String msg) {
        Logger.addMsg(LogLevel.FINE, formatMsg(msg), 1);
    }

    @Override
    public ChannelHandlerContext getChannelCtx() {
        return this.channelCtx;
    }
}
